#include <defs.h>
#include <iostream>
#include <stdio.h>
#include <sys/time.h>
#include <ctime>
#include <TFrame.h>
#include <pppnode.h>
#include <pppmst.h>
#include <translate.h>
#include <boost/graph/random.hpp>
#include <boost/graph/plod_generator.hpp>
#include <boost/random/linear_congruential.hpp>

int 
main() {
	printf("Initializing ... \n");
	const int num_nodes = 100;
	const int num_edges = 10000;
	Graph_t g;

	boost::minstd_rand0 rnd(time(0));
	generate_random_graph(g, (Vsize_t)num_nodes, (Vsize_t)num_edges, rnd, true, false);

	edge_iterator_t e, eend;
	weightmap_t weightmap = get(edge_weight, g);
	int i = 1;
    srand(time(NULL));
	for (tie(e,eend) = edges(g) ; e != eend ; e++) {
		weightmap[*e] = rand()%10;
	}

    PPPWGraph graph;

    translate(g, &graph, num_nodes);
#if 0
    // print boost graph
    vertex_iterator_t v, vend;
    for (tie(v,vend) = vertices(g) ; v != vend; v++) {
        out_edge_iterator_t e, eend;
        for (tie(e, eend) = out_edges(*v, g) ; e != eend ; e++) {
            std::cout << *v << " ----> " << target(*e, g) << " with weight = " << weightmap[*e] << "\n";
        }
    }
    
    std::cout << "*************Boost Graph Done*************\n";

    // print ppp graph
    for (int i = 0 ; i < num_nodes ; i++) {
        std::vector<PPPWEdge>::iterator it;
        for (it = graph.edges[i]->begin() ; it != graph.edges[i]->end() ; it++) {
            std::cout << i << " ----> " << (*it).to << " with weight = " << (*it).w << "\n";
        }
    }
#endif


	WorkQueue * Q = new WorkQueue();
	Q->setNumThreads(3);
	Q->initThreads();

	std::vector < graph_traits < Graph_t >::vertex_descriptor >
		p(num_vertices(g));

	timeval tim;
	double t1, t2;
	printf("Initializing Done\n");

	gettimeofday(&tim, NULL);
	t1=tim.tv_sec+(tim.tv_usec/1000000.0);	
	prim_minimum_spanning_tree(g, &p[0]);
	gettimeofday(&tim, NULL);
	t2=tim.tv_sec+(tim.tv_usec/1000000.0);	
	printf("%.6lf seconds elapsed\n", t2-t1);

    pppmst * mst = new pppmst(Q, &graph, num_nodes);
    Q->addTask(mst);
    Q->wait_for_threads();
#if 0
	t1=tim.tv_sec+(tim.tv_usec/1000000.0);	
	MSTTask_t * mst = new MSTTask_t(&g, Q);
	Q->addTask(mst);
	Q->wait_for_threads();
	gettimeofday(&tim, NULL);
	t2=tim.tv_sec+(tim.tv_usec/1000000.0);	
	printf("%.6lf seconds elapsed\n", t2-t1);
#endif
	return EXIT_SUCCESS;
}
